#include "tcpdatareceiver.h"

 TcpDataReceiver::TcpDataReceiver(QTcpSocket* socket, QObject* parent)
        : m_socket(socket), QObject(parent), m_timeout(3000) {
    }

  void  TcpDataReceiver::  setReadMode(ReadMode mode, QVariant parameter = QVariant()) {
        m_mode = mode;
        m_parameter = parameter;
    }

   void TcpDataReceiver::  setTimeout(int timeoutMs) {
        m_timeout = timeoutMs;
    }
   // 方法1：读取直到遇到结束标志
   QByteArray  TcpDataReceiver::readUntilDelimiter(QTcpSocket* socket, char delimiter, int timeoutMs = 3000) {
       QByteArray data;
      CHRONO_START_TIMER();

       while ( CHRONO_ELAPSED_MS()  < timeoutMs) {
           if (socket->waitForReadyRead(100)) {
               // 读取所有可用数据
               QByteArray chunk = socket->readAll();
               data.append(chunk);

               // 检查是否包含结束标志
               int delimiterPos = data.indexOf(delimiter);
               if (delimiterPos != -1) {
                   // 返回不包括结束标志之前的所有数据
                   qDebug()<<"recv complete";
                   return data.left(delimiterPos);
               }
           }
           // 检查是否超时
           if ( CHRONO_ELAPSED_MS()  >= timeoutMs) {
               qWarning() << "读取数据超时，未找到结束标志";
               break;
           }
       }

       return data; // 返回已读取的数据（可能不完整）
   }
   // 读取固定长度的数据
   QByteArray TcpDataReceiver:: readFixedLength(QTcpSocket* socket, int length, int timeoutMs = 3000) {
       QByteArray data;
       CHRONO_START_TIMER();

       while (data.size() < length && CHRONO_ELAPSED_MS() < timeoutMs) {
           // 计算还需要读取的字节数
           int bytesToRead = length - data.size();

           if (socket->waitForReadyRead(100)) {
               // 读取需要的数据量
               QByteArray chunk = socket->read(bytesToRead);
               data.append(chunk);
           }

           // 检查是否超时
           if (CHRONO_ELAPSED_MS() >= timeoutMs && data.size() < length) {
               qWarning() << "读取数据超时，期望长度:" << length << "实际长度:" << data.size();
               break;
           }
       }

       return data;
   }
   QByteArray TcpDataReceiver::readLengthPrefixedData(QTcpSocket* socket, int timeoutMs = 3000) {
     CHRONO_START_TIMER();

       // 首先读取长度字段（假设为4字节整数）
       QByteArray lengthData = readFixedLength(socket, 4, timeoutMs);
       if (lengthData.size() != 4) {
           qWarning() << "无法读取长度字段";
           return QByteArray();
       }

       // 将字节转换为长度值（网络字节序转主机字节序）
       uint32_t dataLength = 0;
       for (int i = 0; i < 4; ++i) {
           dataLength = (dataLength << 8) | static_cast<unsigned char>(lengthData[i]);
       }

       // 读取实际数据
       return readFixedLength(socket, dataLength, timeoutMs -CHRONO_ELAPSED_MS() );
   }


  QByteArray  TcpDataReceiver::  readData() {
        switch (m_mode) {
        case ReadUntilDelimiter:
            if (m_parameter.canConvert<char>()) {
                return readUntilDelimiter(m_socket,m_parameter.value<QChar>().toLatin1(), m_timeout);
            }
            break;
        case ReadFixedLength:
            if (m_parameter.canConvert<int>()) {
                return readFixedLength(m_socket, m_parameter.toInt(), m_timeout);
            }
            break;
        case ReadLengthPrefixed:
            return readLengthPrefixedData(m_socket, m_timeout);
        }

        qWarning() << "无效的读取模式或参数";
        return QByteArray();
    }

